/*
 *  Copyright (C) <2009>  Pavel Vakeš <pavel.vakes@gmail.com>
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "plasma-gx_mail_notify.h"


PlasmaGXMailNotify::PlasmaGXMailNotify(QObject *parent, const QVariantList &args)
    : Plasma::PopupApplet(parent, args),
    messages_dialog(0), check_messages(0), is_check_error(false)
{
	setAspectRatioMode(Plasma::ConstrainedSquare);
    resize(64, 64);

	messages_dialog = (MessagesDialog *) widget();
}


PlasmaGXMailNotify::~PlasmaGXMailNotify()
{
	delete widget();

	dropMailCheckers();
	dropAccounts();
}

void PlasmaGXMailNotify::init()
{
	loadConfig();
	createMailCheckers();
	messages_dialog->createAccountItems(mail_checkers);
	startMailCheckers();

//	Plasma::ToolTipManager::self()->registerWidget(this);
	if (containment()->containmentType() != Plasma::Containment::PanelContainment) setPopupIcon("");
}

void PlasmaGXMailNotify::constraintsEvent(Plasma::Constraints)
{
	if (containment()->containmentType() == Plasma::Containment::PanelContainment) setBackgroundHints(NoBackground);
}

void PlasmaGXMailNotify::createConfigurationInterface(KConfigDialog *parent)
{
	stopMailCheckers();

	appearance_dialog = new AppearanceDialog();
	appearance_dialog->checkTrayIconSize->setChecked(cfg_tray_icon_size);
	appearance_dialog->selFontFamily->setCurrentFont(cfg_font);

	config_dialog = new ConfigDialog();
	config_dialog->loadAccounts(accounts);

	parent->addPage(appearance_dialog, tr2i18n("Appearance"), "preferences-desktop-theme");
	parent->addPage(config_dialog, tr2i18n("Accounts"), "mail-message");

	connect(parent, SIGNAL( okClicked() ), this, SLOT( saveConfig() ));
	connect(parent, SIGNAL( finished() ), this, SLOT( startMailCheckers() ));
}

void PlasmaGXMailNotify::loadConfig()
{
	KConfigGroup cfg = config();

	cfg_tray_icon_size = cfg.readEntry("tray_icon_size", false);
	cfg_font.setFamily(cfg.readEntry("font_family", font().family()));

	KConfigGroup cfg_accounts(&cfg, "Accounts");

	QStringList account_ids = cfg_accounts.groupList();
	account_ids.sort();

	for (int i = 0; i < account_ids.count(); ++i) {
		Account * account = new Account(new KConfigGroup(&cfg_accounts, account_ids.value(i)));

		if (account->name.isEmpty()) delete account;
		else accounts.push_back(account);
	}
}

void PlasmaGXMailNotify::saveConfig()
{
	dropMailCheckers();

	KConfigGroup cfg = config();

	cfg_tray_icon_size = appearance_dialog->checkTrayIconSize->isChecked();
	cfg.writeEntry("tray_icon_size", cfg_tray_icon_size);
	cfg_font.setFamily(appearance_dialog->selFontFamily->currentFont().family());
	cfg.writeEntry("font_family", cfg_font.family());

	KConfigGroup cfg_accounts(&cfg, "Accounts");
	cfg_accounts.deleteGroup();

	dropAccounts();

	for (int i = 0; i < config_dialog->listAccounts->count(); ++i) {
		KConfigGroup cfg_account(&cfg_accounts, QString::number(i));
		Account * account = new Account(((ListAccountItem *) config_dialog->listAccounts->item(i))->account);
		account->saveConfiguration(&cfg_account);
		accounts.push_back(account);
	}

	cfg.sync();

	createMailCheckers();
	messages_dialog->createAccountItems(mail_checkers);

	update();
}

void PlasmaGXMailNotify::dropAccounts()
{
	while (!accounts.empty()) {
		delete accounts.back();
		accounts.pop_back();
	}
}

void PlasmaGXMailNotify::createMailCheckers()
{
	if (!accounts.empty()) {
		for (unsigned int i = 0; i < accounts.size(); ++i) {
			if (accounts[i]->isReadyForCheck()) {
				MailChecker * mail_checker = new MailChecker(accounts[i]);
				connect(mail_checker, SIGNAL( endCheckMessages(int) ), this, SLOT( refreshState() ));
				connect(mail_checker, SIGNAL( endCheckError(QString) ), this, SLOT( refreshState() ));
				connect(mail_checker, SIGNAL( certificateAccepted(Account *) ), this, SLOT( saveCertificate(Account *) ));
				mail_checkers.push_back(mail_checker);
			}
		}
	}
}

void PlasmaGXMailNotify::dropMailCheckers()
{
	while (!mail_checkers.empty()) {
		mail_checkers.back()->stopCheck();
		delete mail_checkers.back();
		mail_checkers.pop_back();
	}
}

void PlasmaGXMailNotify::startMailCheckers()
{
	check_messages = 0;
	is_check_error = false;

	if (!mail_checkers.empty()) {
		for (unsigned int i = 0; i < mail_checkers.size(); ++i) {
			mail_checkers[i]->startPeriodicallyCheck();
		}
	}
}

void PlasmaGXMailNotify::stopMailCheckers()
{
	if (!mail_checkers.empty()) {
		for (unsigned int i = 0; i < mail_checkers.size(); ++i) {
			mail_checkers[i]->stopCheck();
		}
	}
}

void PlasmaGXMailNotify::refreshState() {
	check_messages = 0;
	is_check_error = false;

	if (!mail_checkers.empty()) {
		for (unsigned int i = 0; i < mail_checkers.size(); ++i) {
			if (!mail_checkers[i]->checkError().isNull()) {
				if (is_check_error == false) is_check_error = true;
			}
			else check_messages += mail_checkers[i]->messages();
		}
	}

	update();
}

void PlasmaGXMailNotify::saveCertificate(Account * account) {
	KConfigGroup cfg = config();
	KConfigGroup cfg_accounts(&cfg, "Accounts");

	for (unsigned int i = 0; i < accounts.size(); ++i) if (accounts[i] == account) {
		KConfigGroup cfg_account(&cfg_accounts, QString::number(i));
		account->saveConfiguration(&cfg_account);
	}

	cfg.sync();
}

void PlasmaGXMailNotify::paintInterface(QPainter *p,
        const QStyleOptionGraphicsItem *, const QRect &contentsRect)
{
	if (containment()->containmentType() != Plasma::Containment::PanelContainment) return;

    p->setRenderHint(QPainter::SmoothPixmapTransform);
    p->setRenderHint(QPainter::Antialiasing);

    // Main icon
	Plasma::Svg icon_main;
	icon_main.setImagePath("widgets/gx_mail_notify-normal");
	QSize size_main = icon_main.size();

	if (cfg_tray_icon_size) size_main.scale(32, 32, Qt::KeepAspectRatio);
	else size_main.scale(contentsRect.width(), contentsRect.height(), Qt::KeepAspectRatio);

	icon_main.resize(size_main);

	int main_top = contentsRect.height() / 2 - size_main.height() / 2;
    icon_main.paint(p, 0, main_top);

    if (check_messages > 0) {
		Plasma::Svg icon_new;
		icon_new.setImagePath("widgets/gx_mail_notify-icon_new");
		QSize size_new = icon_new.size();
		size_new.scale(size_main.width() / 3, 0, Qt::KeepAspectRatioByExpanding);
		icon_new.resize(size_new);
		icon_new.paint(p, size_main.width() - size_new.width(), main_top - size_new.height() / 4);
    }

	if (is_check_error) {
		Plasma::Svg icon_error;
		icon_error.setImagePath("widgets/gx_mail_notify-icon_error");
		QSize size_error = icon_error.size();
		size_error = icon_error.size();
		size_error.scale(size_main.width() / 3.5, 0, Qt::KeepAspectRatioByExpanding);
		icon_error.resize(size_error);
		icon_error.paint(p, 0, main_top - size_error.height() / 5);
	}

	QRect textRect(QPoint(0, main_top), size_main);
	cfg_font.setBold(true);
	cfg_font.setPixelSize(textRect.height() / 2.7 < 12 ? 12 : textRect.height() / 2.7);
	p->setFont(cfg_font);
    p->setPen(Qt::black);

	p->drawText(textRect, (size_main.height() <= 32 ? Qt::AlignVCenter : Qt::AlignBottom) | Qt::AlignHCenter, QString::number(check_messages));
}

//void PlasmaGXMailNotify::toolTipAboutToShow() {
//	Plasma::ToolTipContent data;
//
//	data.setAutohide(false);
//
//	QString messages_text;
//	QString errors_text;
//
//	if (!mail_checkers.empty()) {
//		for (unsigned int i = 0; i < mail_checkers.size(); ++i) {
//
//			if (mail_checkers[i]->messages() > 0) {
//				if (!messages_text.isEmpty()) messages_text.append(", ");
//				messages_text.append(mail_checkers[i]->accountName() + " (" + QString::number(mail_checkers[i]->messages()) + ")");
//			}
//
//			if (!mail_checkers[i]->checkError().isNull()) {
//				if (!errors_text.isEmpty()) errors_text.append(", ");
//				errors_text.append(mail_checkers[i]->accountName() + " (" + mail_checkers[i]->checkError() + ")");
//			}
//		}
//	}
//
//	data.setMainText("Messages: " + (messages_text.isEmpty() ? "No messages" : messages_text));
//	data.setSubText("Errors: " + (errors_text.isEmpty() ? "No errors" : errors_text));
//
//	Plasma::ToolTipManager::self()->setContent(this, data);
//}
//
//void PlasmaGXMailNotify::toolTipHidden() {
//	Plasma::ToolTipManager::self()->clearContent(this);
//}

QWidget * PlasmaGXMailNotify::widget()
{
	if (!messages_dialog) {
		messages_dialog = new MessagesDialog();
	}

	return messages_dialog;
}

#include "plasma-gx_mail_notify.moc"
